from queue import Queue
from MyLib.CarApi.TestToolApi import Debug
import subprocess as sb
import time
import threading


class DevInit:

    def __init__(self) -> None:
        # <<<<<<<<<< 4G网络操作指令 >>>>>>>>>> #
        self.__netTaskThread = None
        self.__checkNetActCmd = 'sudo ip route | grep "default via 10.64.64.64 dev ppp0"'
        self.__checkNetDevOkCmd = 'lsusb | grep "EC25 LTE modem"'
        self.__checkNetOpenedCmd = 'ifconfig | grep ppp0'
        self.__netOpenCmd = "nohup sudo wvdial lan1 > /home/pi/Documents/Logs/netrun.log 2>&1 &"

        self.__glLogFilePath = "/home/pi/Documents/Logs/{}"
        self.__glDebugQueue = Queue(1)
        self.__netTaskDebug = Debug(self.__glDebugQueue, True, "网络设备监听模块",
                                    file_name=self.__glLogFilePath.format("NetTask.log"))

    def __cmd(self, command: str, times: int = 3):
        sub = sb.Popen(command, shell=True,
                       stderr=sb.PIPE, stdout=sb.PIPE)
        sub.wait(times)
        stdout, stderr = sub.communicate()
        if stdout and stderr:
            return stdout, stderr
        elif stdout:
            return stdout
        elif stderr:
            return stderr
        else:
            return None

    def __netTask(self, waitTime):
        self.__netTaskDebug.debug("-----网络设备检查线程开始-----")
        pppTimes = 0
        routeTimes = 0
        netTimes = 0
        allTimes = 0
        while True:
            if pppTimes >= 5:
                self.__netTaskDebug.warn("PPP拨号失败多次，进入警备待机线程！")
                break
            if routeTimes >= 10:
                self.__netTaskDebug.warn("路由添加失败多次，进入警备待机线程！")
                break
            netDevCheck = self.__cmd(self.__checkNetDevOkCmd)
            if netDevCheck is not None:
                netTimes = 0
                netPPPCheck = self.__cmd(self.__checkNetOpenedCmd)
                if netPPPCheck is not None:
                    pppTimes = 0
                    netIpCheck = self.__cmd(self.__checkNetActCmd)
                    if netIpCheck is not None:
                        routeTimes = 0
                        self.__netTaskDebug.debug(f"-----网络运行无问题!这是第[{allTimes}]次检查，{waitTime}s后开启下轮-----")
                        time.sleep(waitTime)
                    else:
                        routeTimes += 1
                        self.__netTaskDebug.warn("网络IP并未加入到路由表中!")
                        self.__cmd("sudo ip route add default via 10.64.64.64")
                        self.__netTaskDebug.debug("已尝试将IP加入到路由表中")
                        time.sleep(1)
                else:
                    pppTimes += 1
                    self.__netTaskDebug.warn("设备未拨号，即将进行拨号！")
                    self.__cmd(self.__netOpenCmd)
                    self.__netTaskDebug.debug("检查拨号状态...预计时间30s左右")
                    nums = 0
                    lastTime = time.time()
                    while nums <= 50:
                        netInPPPCheck = self.__cmd(self.__checkNetOpenedCmd)
                        if netInPPPCheck is None:
                            time.sleep(1)
                            nums += 1
                        else:
                            nowTime = time.time()
                            self.__netTaskDebug.debug(f"拨号成功，所用时间为[{round(nowTime - lastTime)}]s")
                            break
                    time.sleep(1)
            else:
                if netTimes >= 60:
                    self.__netTaskDebug.warn("网络设备出现问题，进入警备线程!")
                    break
                self.__netTaskDebug.warn(f"网络设备貌似在启动中，进行轮询等待, 这是第{netTimes}次...")
                time.sleep(1)
                netTimes += 1
            allTimes += 1
        self.__netTaskDebug.debug("-----网络设备检查线程结束-----")

    def openNetTask(self, waitTime=5):
        """
        描述：打开网络检查线程
        参数：@waitTime[int]->等待时间
        返回值：无
        """
        self.__netTaskThread = threading.Thread(target=self.__netTask, args=(waitTime,))
        self.__netTaskThread.start()

    def waitNetTaskEnded(self):
        self.__netTaskThread.join()


if "__main__" == __name__:
    testInit = DevInit()
    testInit.openNetTask()
    testInit.waitNetTaskEnded()
